<?php
/**
 * 清理缓存 自定义公共组件
 * User: apple
 * Date: 1/23/22
 * Time: 9:54 PM
 */

use \app\assets\BackendAsset as Asset;
use \app\models\tableModel\AdminRoleModel;

/* @var $this yii\web\View */
/* @var $_params_ array 总参数变量 */
/* @var $cacheUrl string|array 选择性清理连接
 *  - 参考{web/js/backend/setting.js -> _url -> clearCache 的键|key}
 */

// 是否展示提交按钮
$showSubmitBtn = empty($cacheUrl) ? 'true' : 'false';

// 转化下自定义清理连接
$cacheUrl = json_encode(
    !empty($cacheUrl) && is_array($cacheUrl) ? $cacheUrl : []
    , JSON_UNESCAPED_UNICODE);

// HTML
$template = <<<EOL

<el-dialog title="清理缓存" :visible.sync="showDialog" :lock-scroll="true" modal-append-to-body
    class="dialog-medium scroll-dialog body-nop clear-wrapper"
    :close-on-click-modal="false">

    <el-scrollbar class="main-scroller">
        <el-container class="clear-wrapper">
            <el-main class="content-wrapper p-15 bg-white">
                <transition name="fadeInDown">
                    <div v-if="showCheckbox">
                        <el-checkbox :indeterminate="isCheckHalf" v-model="isCheckAll"
                                     @change="handleCkAllChange">
                            全选
                        </el-checkbox>
                        <div class="mt-15 mb-15"></div>
                        <el-checkbox-group v-model="checkedApis" @change="handleCheckedChange">
                            <el-checkbox v-for="(item, key) in apiList" :label="key" :key="key">
                                {{item.name}}
                            </el-checkbox>
                        </el-checkbox-group>
                    </div>
                </transition>
                <el-timeline v-show="showTimeline">
                    <transition-group name="fadeInDown">
                        <el-timeline-item v-for="(item, key) in messageList"
                                          :timestamp="item.timestamp"
                                          v-bind:key="key" :icon="item.icon"
                                          :type="item.type" :color="item.color">
                            <span v-if="item.type === 'primary'">
                                {{item.title}}
                            </span>
                            <span v-else-if="item.type === 'loading'">
                                <i class="el-icon-loading"></i>&nbsp;{{item.title}}
                            </span>
                            <span :class="'text-' + item.type" v-else-if="item.type !== 'success'">
                                {{item.title}}
                            </span>
                            <span :class="'text-' + item.type" v-else>
                                {{item.title}}
                            </span>
                        </el-timeline-item>
                    </transition-group>
                </el-timeline>
            </el-main>
        </el-container>
    </el-scrollbar>
    
    <div slot="footer" class="text-center">
        <el-button type="danger" size="mini" @click="showDialog = false">关闭</el-button>
EOL;
if (AdminRoleModel::checkAuth('cache/*')) {
    $template .= <<<EOL
    
        <el-button size="mini" type="primary" @click="clearCache(false)" v-if="{$showSubmitBtn}">
            提交
        </el-button>

EOL;
}
$template .= <<<EOL

    </div>
</el-dialog>

EOL;

$js = <<<EOL
Vue.component('clear-cache', {
    template: `$template`,
    props: {
        cacheUrl: { // 选择性清理连接
            type: [String, Array],
            default: []
        },
    },
    data: function () {
        return {
            showDialog: false,   // 是否展示弹出层
            overRetList: true,   // 完毕返回列表
            apiList: {},         // 连接列表
            checkedApis: [],     // 点选的连接列表
            isCheckAll: false,   // 是否已全选
            isCheckHalf: false,  // 是否半选
            showCheckbox: false, // 显示选择按钮
            showTimeline: false, // 显示时间线
            messageList: {},     // 提醒文本
        };
    },
    created: function () {

        var that = this;
        this.\$nextTick(function () {});
    },
    methods: {
        /**
         * 执行清理缓存
         * @param \$key 当前键(checkedApis里的一条数据)
         * @param \$page 清理的当前缓存的第几页(因为有可能数据多分页当前第几页)
         * @returns {*|void}
         */
        clearCache: function (\$key, \$page) {

            // 检测未选择提醒
            if (!\$key && this.checkedApis.length < 1) {
                return this.\$message({
                    type: 'error',
                    showClose: true,
                    message: '请选择一个条目进行清理'
                });
            }

            // 清空消息线
            if (!\$key || \$key === true) this.messageList = {};
            // 隐藏 选择框
            this.showCheckbox = false;
            // 显示时间线
            this.showTimeline = true;

            this.\$set(this.messageList, 'updating', {
                title: '刷新中...',
                timestamp: \$w.formatDate(new Date(), 'Y-m-d H:i:s'),
                type: "loading",
            });

            // 如果[执行已选择键不存在] - 默认
            if (!\$key) \$key = this.checkedApis[0];
            // 当前即将请求的
            var clearInfo = this.apiList[\$key];
            // 长度超过返回下 - 一般是执行完毕了
            if (!clearInfo) {
                // 添加下完毕时间线
                return this.addEndTimeLine();
            }
            // 验证其连接
            // 长度超过返回下
            if (!clearInfo['url']) {
                // 错误打印台打印下
                console.warn(
                    '连接数据【' +
                    (clearInfo['name'] ? clearInfo['name'] : \$key) +
                    '】不存在，' +
                    '请到核心JS文件中：/js/backend/setting.js -> `_url[clearCache]`检查相关设置。'
                );

                // 下一条 - 下一个键为参数
                return this.clearCache(
                    \$w.array_next_val(\$key, this.checkedApis, 'value')
                );
            }

            \$page = parseInt(\$page || 1);
            // 连接
            var url = \$w.getApiUrl('_prefix') + this.apiList[\$key]['url'];

            var that = this;

            // 获取各模块的值
            $.ajax({
                url: url,
                type: 'get',
                data: {page: \$page},
                dataType: "json",
                complete: function (event) {

                    // 首先删除掉正在加载条目
                    that.\$delete(that.messageList, 'updating');
                    that.\$nextTick(function () {

                        if (that.\$refs['scroll'] && that.\$refs['scroll'].wrap)
                            that.\$refs['scroll'].wrap.scrollTop =
                                that.\$refs['scroll']['\$el']['clientHeight'];
                    });

                    // 必须先登录
                    if (parseInt(event.responseJSON.no) === 401) {

                        that.\$message({
                            type: 'warning',
                            showClose: true,
                            message: '登录超时，请重新登录'
                        });

                        // 几秒之后移除
                        return setTimeout(function () {
                            window.parent.location.href = \$w.getPageUrl('login');
                        }, 810);
                    }

                    // 操作失败显示错误信息
                    if (parseInt(event.responseJSON.no) !== 200) {

                        // 失败文本
                        return that.\$set(that.messageList, \$key + '_' + \$page, {
                            title: event.responseJSON.msg,
                            timestamp: \$w.formatDate(new Date(), 'Y-m-d H:i:s'),
                            icon: "el-icon-error",
                            type: "danger",
                            color: "#ff0000"
                        });
                    }

                    // 成功文本
                    that.\$set(that.messageList, \$key + '_' + \$page, {
                        title: event.responseJSON.msg,
                        timestamp: \$w.formatDate(new Date(), 'Y-m-d H:i:s'),
                        icon: "el-icon-success",
                        type: "primary",
                        color: "#0bbd87"
                    });
                    // 下一页还有数据
                    if (event.responseJSON.data.nextPageHave === true) {
                        return that.clearCache(\$key, \$page + 1);
                    }

                    // 检测是否全部连接加载完毕，没完毕继续加载下一条
                    var nextKey = \$w.array_next_val(\$key, that.checkedApis, 'value');
                    if (nextKey) return that.clearCache(nextKey);

                    // 添加完毕时间线
                    that.addEndTimeLine();
                }
            });
        },
        /**
         * 添加下完毕时间线
         * @param \$dontResetUi 是否[不要重置UI]
         * @returns {boolean}
         */
        addEndTimeLine: function (\$dontResetUi) {

            // 时间线有[update]的话 - 删除
            if (this.messageList['updating']) {
                // 首先删除掉正在加载条目
                this.\$delete(this.messageList, 'updating');
            }
            // 未添加结束标语添加
            if (!this.messageList['end']) {

                // 最后全部加载完毕
                this.\$set(this.messageList, 'end', {
                    title: '缓存刷新完毕' + (this.overRetList ? '，正在返回，请稍后...' : ''),
                    timestamp: \$w.formatDate(new Date(), 'Y-m-d H:i:s'),
                    icon: "el-icon-success",
                    type: "success",
                    color: "#0bbd87"
                });
            }

            // 不要重置UI
            if (\$dontResetUi || !this.overRetList) return true;
            // 隔几秒在展示出选择列表
            var that = this;
            setTimeout(function () {
                // 先隐藏 时间线
                that.showTimeline = false;
                // 展示 选择框
                that.showCheckbox = true;
            }, 2800);
        },
        /**
         * 传输的自定义缓存清除参数[默认点选]
         * @param \$cacheUrls
         */
        customApiList: function (\$cacheUrls) {
            // 连接长度小于[1]
            if (!\$cacheUrls || \$cacheUrls.length < 1) return false;
            if (typeof \$cacheUrls === 'string') \$cacheUrls = [\$cacheUrls];
            for (var i in \$cacheUrls) {
                if (!\$cacheUrls.hasOwnProperty(i)) continue;
                // 不在当前缓存合法列表中
                if (!\$w.in_array(\$cacheUrls[i], Object.keys(this.apiList))) {
                    // 姑且报个错提醒下
                    console.warn('连接数据【' + \$cacheUrls[i] + '】不是合法更新缓存【KEY】，' +
                        '请检查(如果确实需要清理此连接的缓存，请到核心JS文件中：' +
                        '/js/backend/setting.js' +
                        ' -> ' +
                        '`_url[clearCache]`添加相关设置)。');
                    this.\$delete(\$cacheUrls, i);
                    // 下一条
                    continue;
                }
                // 已经在选择列表中 下一条
                if (\$w.in_array(\$cacheUrls[i], this.checkedApis)) continue;

                // 加入已选择
                this.checkedApis.push(\$cacheUrls[i]);
            }

            // 如果传入了参数最终触发下单选改变
            if (this.checkedApis.length > 0) this.handleCheckedChange();

            return this.checkedApis;
        },
        /**
         * 监测全选
         * @param \$value
         * @returns {boolean}
         */
        handleCkAllChange: function (\$value) {
            // 取消全选
            if (!\$value) {
                // 当前点选数据清空
                this.checkedApis = [];
                // 全选
                this.isCheckAll = false;
                // 非半选
                return this.isCheckHalf = false;
            }

            // 否则全选循环赋值
            this.checkedApis = [];
            for (var i in this.apiList) {
                if (!this.apiList.hasOwnProperty(i)) continue;
                this.checkedApis.push(i);
            }
            // 全选
            this.isCheckAll = true;
            // 非半选
            return this.isCheckHalf = false;
        },
        /**
         * 单选点击
         * @param \$value
         */
        handleCheckedChange: function (\$value) {
            var checkedCount = \$value ? \$value.length : this.checkedApis.length;
            // 是否已经全选
            this.isCheckAll = (checkedCount === Object.keys(this.apiList).length);
            // 是否半选
            this.isCheckHalf = (
                checkedCount > 0 && checkedCount < Object.keys(this.apiList).length
            );
        }
    },
    watch: {
        /**
         * 监测弹出层状态
         */
        showDialog: function (\$val) {
        
            if (!\$val) return false;
            
            // 或取出缓存[API]列表
            this.apiList = \$w.getApiUrl('clearCache');
    
            // 获取参数 - 已检测是否是清除规定缓存
            var cacheUrl = JSON.parse('{$cacheUrl}');
            if (cacheUrl && this.customApiList(cacheUrl).length > 0) {
                // 完毕不返回列表了
                this.overRetList = false;
                // this.customApiList(cacheUrl);
            }
    
            var that = this;
            this.\$nextTick(function () {
                // 结束展示列表 先展示选择框
                if (this.overRetList) that.showCheckbox = true;
                // 结束不展示列表 直接开始清理
                if (!this.overRetList) that.clearCache();
            });
        }
    }
});
EOL;
if (empty($this->params['reg_clear_cache'])) Asset::addCss($this, '/css/backend/clear-cache.css');
if (empty($this->params['reg_clear_cache'])) $this->registerJs($js);
// 已注册过
$this->params['reg_clear_cache'] = true;

echo "<clear-cache ref=\"clearCache\"></clear-cache>";
?>
